package controller

import (
	"exporter/models"
	"exporter/service"
	"exporter/setting"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"os"
	"time"
)

/*
 url     --> controller  --> logic   -->    model
请求来了  -->  控制器      --> 业务逻辑  --> 模型层的增删改查
*/

func IndexHandler(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", nil)
}

func GetAProcess(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	proc, err := models.GetAProcess(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	} else {
		c.JSON(http.StatusOK, proc)
	}
}

func CreateProcess(c *gin.Context) {
	// 前端页面填写待办事项 点击提交 会发请求到这里
	// 1. 从请求中把数据拿出来
	var prc models.Process
	c.BindJSON(&prc)
	// 2. 存入数据库
	prc.Status = false
	podIP := os.Getenv("POD_IP")
	if podIP == "" {
		podIP = "localhost"
	}
	prc.IP = podIP
	prc.StartTime = time.Now()
	prc.Pid = -1
	err := models.CreateAProcess(&prc)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	} else {
		c.JSON(http.StatusOK, prc)
		//c.JSON(http.StatusOK, gin.H{
		//	"code": 2000,
		//	"msg": "success",
		//	"data": todo,
		//})
	}
}

func GetProcessList(c *gin.Context) {
	// 查询todo这个表里的所有数据
	todoList, err := models.GetAllProcess()
	service.SetProcessListStatus(todoList)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	} else {
		c.JSON(http.StatusOK, todoList)
	}
}

func UpdateAProcess(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	todo, err := models.GetAProcess(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}
	c.BindJSON(&todo)
	if err = models.UpdateAProcess(todo); err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	} else {
		c.JSON(http.StatusOK, todo)
	}
}

func DeleteAProcess(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	process, _ := models.GetAProcess(id)
	if process.Status {
		c.JSON(http.StatusOK, gin.H{"error": "程序正在运行中，不可以删除"})
	}
	if err := models.DeleteAProcess(id); err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
	} else {
		c.JSON(http.StatusOK, gin.H{id: "deleted"})
	}
}

func StartAProcess(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	//process, err := models.GetAProcess(id)
	processList, err := models.GetProcessList(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}
	for _, process := range processList {
		go service.StartCommand(c, *process)
	}
	//go service.Main2()
	c.JSON(http.StatusOK, gin.H{"msg": "执行成功"})
}

func StopAProcess(c *gin.Context) {

	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	//process, err := models.GetAProcess(id)
	processList, err := models.GetProcessList(id)

	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}
	for _, process := range processList {
		err = service.ShutdownCommand(*process)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{"error": "shutdown command [" + process.Name + "] error with " + err.Error()})
			return
		}
	}

	c.JSON(http.StatusOK, gin.H{"msg": "执行成功"})
}

func GetMetrics(c *gin.Context) {
	str, _ := service.GetMetrics()
	c.String(http.StatusOK, str)
}

func GetExporterInfo(c *gin.Context) {
	podIP := os.Getenv("EXPORTER_IP")
	if podIP == "" {
		podIP = "localhost"
	}
	exporterName := os.Getenv("EXPORTER_NAME")
	if exporterName == "" {
		exporterName = setting.Conf.Name
	}
	version := os.Getenv("EXPORTER_VERSION")
	if version == "" {
		version = "v0.0.2"
	}
	exporterInfo := map[string]string{
		"exporterName": exporterName,
		"IP":           podIP,
		"version":      version,
	}
	c.JSON(http.StatusOK, exporterInfo)

}

type ParamRequest struct {
	Ids []string `json:"ids" form:"ids"`
}

func DeleteProcess(c *gin.Context) {
	req := &ParamRequest{}
	// 绑定参数
	if err := c.ShouldBind(req); err != nil {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	for _, id := range req.Ids {
		if err := models.DeleteAProcess(id); err != nil {
			c.JSON(http.StatusOK, gin.H{"error": err.Error()})
			return
		}
	}
	c.JSON(http.StatusOK, gin.H{"msg": "删除成功!"})
}

func UploadFile(c *gin.Context) {
	// 单个文件
	file, err := c.FormFile("f1")
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
		})
		return
	}
	log.Println(file.Filename)
	dst := fmt.Sprintf("/tmp/%s", file.Filename)
	// 上传文件到指定的目录
	c.SaveUploadedFile(file, dst)
	c.JSON(http.StatusOK, gin.H{
		"message": fmt.Sprintf("'%s' uploaded!", file.Filename),
	})
}

func UploadFiles(c *gin.Context) {
	// Multipart form
	form, _ := c.MultipartForm()
	files := form.File["file"]

	for index, file := range files {
		log.Println(file.Filename)
		dst := fmt.Sprintf("/tmp/%s_%d", file.Filename, index)
		// 上传文件到指定的目录
		c.SaveUploadedFile(file, dst)
	}
	c.JSON(http.StatusOK, gin.H{
		"message": fmt.Sprintf("%d files uploaded!", len(files)),
	})
}

func GetProcessLog(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	proc, err := models.GetAProcess(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"error": err.Error()})
		return
	}
	service.ViewLogs(c, *proc)
}
